// $Id: Transition.cs 124 2007-05-28 15:51:51Z xavex2k $

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Diagram.Model;
using PetriDiagram.Model;

namespace PetriDiagram
{
    [Serializable]
    public class Transition : PetriNetEntity
    {
        public Transition( PetriNetModel net )
            : base( net )
        { }

        public override ICollection<PetriNetEntity> Inputs
        {
            get
            {
                return new ReadOnlyCollection<PetriNetEntity>( Net.GetInputs( this ) );
            }

        }

        public override ICollection<PetriNetEntity> Outputs
        {
            get
            {
                return new ReadOnlyCollection<PetriNetEntity>( Net.GetOutputs( this ) ); ;
            }
        }

        //public override Entity Clone()
        //{
        //    return new Transition( Net );
        //}

        public override Diagram.IUndoable GetInstance()
        {
            return new Transition( Net );
        }

        public override string CreateDefaultName()
        {
            return NameManager.Instance.GetName( GetType(), "t" );
        }

        public bool IsActive
        {
            get
            {
                ICollection<PetriNetRelation> connections = Net.GetIncommingConnections( this );

                foreach( PetriNetRelation relation in connections )
                {
                    if( relation.Weight > (relation.From as Place).Tokens )
                        return false;                   
                }



                ICollection<InhibitorArc> inhibitors = Net.GetIncomingInhibitors( this );

                foreach( InhibitorArc relation in inhibitors )
                {
                    if( (relation.From as Place).Tokens > 0 )
                        return false;
                }


                return true;
            }
        }

        public void Fire()
        {
            if( !IsActive )
                return;
            
            ICollection<PetriNetRelation> incomming = Net.GetIncommingConnections( this );
            ICollection<PetriNetRelation> outgoing  = Net.GetOutgoingConnections( this );

            foreach( PetriNetRelation relation in incomming )
                if( relation is PetriNetRelation )
                    ( relation.From as Place ).Tokens -= relation.Weight;

            foreach( PetriNetRelation relation in outgoing )
            {
                ( relation.To as Place ).Tokens += relation.Weight;
            }
        }
    }
}
